/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014-2016 abel533@gmail.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.is.add.service.impl;

import com.github.pagehelper.PageHelper;
import com.is.add.controller.vo.DataCountPageListVO;
import com.is.add.controller.vo.GeneralTableVO;
import com.is.add.enmus.*;
import com.is.add.mapper.OrderMapper;
import com.is.add.mapper.ShopMapper;
import com.is.add.mapper.SportsTypeMapper;
import com.is.add.model.*;
import com.is.add.service.OrderService;
import com.is.add.util.*;
import com.is.add.util.DateUtil.DateStyle;
import com.is.add.util.DateUtil.DateUtil;
import com.is.add.util.DimensionUtil.*;
import com.is.add.util.ExcelUtil.ExcelTemplate;
import com.is.add.util.ExcelUtil.ExcelUtil;
import com.is.add.util.ExcelUtil.GetPath;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author liuzh
 * @since 2015-12-19 11:09
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private CityServiceImpl cityService;
    @Autowired
    private SportsTypeMapper sportsTypeMapper;
    @Autowired
    private ShopMapper shopMapper;

    private static final String FILE_SEPARATOR = System.getProperties().getProperty("file.separator");
    private static String excelPath = "/home/settlePT/excel/";

    private static Map<String,Dimension<OrderBase>> orderDimensions=new HashMap<>(7);
    static{
        orderDimensions.put("shop",new ShopDimension());
        orderDimensions.put("payType",new PayTypeDimension());
        orderDimensions.put("city",new CityDimension());
        orderDimensions.put("sales",new SalesDimension());
        orderDimensions.put("sportsType",new SportsTypeDimension());
        orderDimensions.put("orderType",new OrderTypeDimension());
        orderDimensions.put("orderStatus",new OrderStatusDimension());
    }


    /**
     * 订单数据(userorder_fixed表)
     * @param dimensions            维度
     * @param map                   条件
     * @return                      DataCount
     */
    @Override
    public DataCount getAllOrder(String [] dimensions, Map<String,String> map) {
        List<OrderBase> baseList=orderMapper.selectAllOrderBase(map);
        List<Dimension<OrderBase>> list=new ArrayList<>();
        for (String key : dimensions){
            list.add(OrderServiceImpl.orderDimensions.get(key));
        }
        return StatisticMaster.loadResult(baseList,list);
    }

    /**
     * 实时订单数据(userorder表)
     * @param dimensions            维度
     * @param map                   条件
     * @return                      DataCount
     */
    @Override
    public DataCount getRecentlyOrder(String [] dimensions, Map<String,String> map) {
        List<OrderBase> baseList=orderMapper.selectRecentlyOrderBase(map);
        List<Dimension<OrderBase>> list=new ArrayList<>();
        for (String key : dimensions){
            list.add(OrderServiceImpl.orderDimensions.get(key));
        }
        return StatisticMaster.loadResult(baseList,list);
    }

    @Override
    public OrderRankingData sumRecentlyOrderBase(Map<String, String> map) {
        return this.orderMapper.sumRecentlyOrderBase(map);
    }

    /**
     * 数据统计页下拉菜单
     */
    @Override
    public DataCountPageListVO getSelectList() {
        List<KeyValue> orderType = OrderType.toList();
        List<KeyValue> payType = PayType.toList();
        List<KeyValue> sportsType =new ArrayList<>();
        List<SportsType> sportsTypeList = this.sportsTypeMapper.selectSportsType();
        for (SportsType st :sportsTypeList){
            sportsType.add(new KeyValue(st.getSportsTypeId().toString(), st.getSportsTypeName()));
        }
        List<KeyValue> cityType = new ArrayList<>();
        List<City> cityList = this.cityService.getCityList();
        for (City city :cityList){
            cityType.add(new KeyValue(city.getCityId().toString(), city.getCityName()));
        }
        List<KeyValue> orderStatus = OrderStatus.toList();
        List<KeyValue> timeType = TimeType.toList();
        List<KeyValue> dimension = DimensionEnum.toList();
        return new DataCountPageListVO(sportsType,payType,cityType,orderType,orderStatus,timeType,dimension);
    }

    /**
     * 数据统计明细
     */
    @Override
    public List<OrderBase> getDataCountDetails(Map<String, String> map, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return orderMapper.selectAllOrderBase(map);
    }
    /**
     * 数据统计明细导出
     */
    @Override
    public void exportDataCountDetails(HttpServletRequest request, HttpServletResponse response, Map<String, String> map) {
        //设置路径
        String docsPath = GetPath.getDirectoryPath("src","main","resources","templates");       //模板文件路径
        String fileName = "数据统计明细表"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls";           //导出Excel文件名
        String filePath = docsPath + FILE_SEPARATOR + fileName;

        filePath = excelPath + fileName;
        //数据填充
        ExcelUtil<OrderBase> ex = new ExcelUtil<OrderBase>();
        String[] headers ={"场馆Id","场馆编号","场馆名称","运动类型","预定量","订单号","订单编号","交易类型","交易额","补贴额",
                "订单时间","消费时间","验证时间","订单类型","订单状态","结算状态"};
        String[] columns={ "shopId", "shopCode", "shopName","sportsTypeName","orderNum","orderId", "orderNumber", "payType", "paySum",
                "subsidySum","orderTime","examineTime","useTime","orderType","statusName","settleStatusName"};
        List<OrderBase> dataset = orderMapper.selectAllOrderBase(map);
        try {
            OutputStream out = new FileOutputStream(filePath);
            ex.exportExcel("数据统计明细表",headers, columns, dataset, out, DateStyle.YYYY_MM_DD_HH_MM_EN.getValue());
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.err.println("文件未找到");
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("IO异常错误");
        } catch (Exception e) {
            e.printStackTrace();
        }
        ExcelUtil.download(filePath, response);
    }
    /**
     * 周结算订单修复
     */
    @Override
    public Integer updateSettleFix(Map<String, Object> map) {
        return orderMapper.updateSettleFix(map);
    }

    /**
     * 导出财务-业务综合表
     * 基于模版
     */
    @Override
    public void exportGeneralExcel(HttpServletResponse response, String startTime, String endTime){
        //设置路径
        String docsPath = GetPath.getDirectoryPath("src","main","resources","templates");       //模板文件路径
        String templateName = "DateCountTemplate.xls";                                          // Excel模版名称
        String templatePath = docsPath + FILE_SEPARATOR + templateName;
        String fileName = "财务-业务数据表"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xls";           //导出Excel文件名
        String filePath = docsPath + FILE_SEPARATOR + fileName;

        filePath = excelPath + fileName;
        //导出文件路径
        ExcelTemplate excel = ExcelTemplate.getInstance().readTemplatePath(templatePath);
        //查询数据显示
        List<GeneralTableVO> dataList = this.loadGeneralData(startTime,endTime);
        for (GeneralTableVO vo : dataList){
            excel.creatNewRow();
            excel.createNewCol(vo.getShopId());
            excel.createNewCol(vo.getShopCode());
            excel.createNewCol(vo.getShopName());
            excel.createNewCol(vo.getSportsType());
            excel.createNewCol(vo.getTotalOrderNum());
            excel.createNewCol(vo.getTotalStadiumNum());
            excel.createNewCol(vo.getTotalFee());
            excel.createNewCol(vo.getTotalSum());
            excel.createNewCol(vo.getPaySum());
            excel.createNewCol(vo.getSettleSum());
            excel.createNewCol(vo.getOrderFee());
            excel.createNewCol(vo.getSubsidySum());
            excel.createNewCol(vo.getSubsidyFee());

            excel.createNewCol(vo.getVipDiscountOrderNum());
            excel.createNewCol(vo.getVipDiscountStadiumNum());
            excel.createNewCol(vo.getVipCheapOrderNum());
            excel.createNewCol(vo.getVipCheapStadiumNum());
            excel.createNewCol(vo.getVipDiscountPaySum());
            excel.createNewCol(vo.getVipCheapPaySum());
            excel.createNewCol(vo.getVipDiscountSettleSum());
            excel.createNewCol(vo.getVipCheapSettleSum());
            excel.createNewCol(vo.getVipDiscountOrderFee());
            excel.createNewCol(vo.getVipCheapOrderFee());
            excel.createNewCol(vo.getVipDiscountSubsidySum());
            excel.createNewCol(vo.getVipDiscountSubsidyFee());

            excel.createNewCol(vo.getAliDiscountOrderNum());
            excel.createNewCol(vo.getAliDiscountStadiumNum());
            excel.createNewCol(vo.getAliCheapOrderNum());
            excel.createNewCol(vo.getAliCheapStadiumNum());
            excel.createNewCol(vo.getAliDiscountPaySum());
            excel.createNewCol(vo.getAliCheapPaySum());
            excel.createNewCol(vo.getAliDiscountSettleSum());
            excel.createNewCol(vo.getAliCheapSettleSum());
            excel.createNewCol(vo.getAliDiscountOrderFee());
            excel.createNewCol(vo.getAliCheapOrderFee());
            excel.createNewCol(vo.getAliDiscountSubsidySum());
            excel.createNewCol(vo.getAliDiscountSubsidyFee());

            excel.createNewCol(vo.getOtherDiscountOrderNum());
            excel.createNewCol(vo.getOtherDiscountStadiumNum());
            excel.createNewCol(vo.getOtherCheapOrderNum());
            excel.createNewCol(vo.getOtherCheapStadiumNum());
            excel.createNewCol(vo.getOtherDiscountPaySum());
            excel.createNewCol(vo.getOtherCheapPaySum());
            excel.createNewCol(vo.getOtherDiscountSettleSum());
            excel.createNewCol(vo.getOtherCheapSettleSum());
            excel.createNewCol(vo.getOtherDiscountOrderFee());
            excel.createNewCol(vo.getOtherCheapOrderFee());
            excel.createNewCol(vo.getOtherDiscountSubsidySum());
            excel.createNewCol(vo.getOtherDiscountSubsidyFee());

            excel.createNewCol(vo.getFreeOrderNum());
            excel.createNewCol(vo.getFreeStadiumNum());
            excel.createNewCol(vo.getFreeSettleSum());
            excel.createNewCol(vo.getFreeSubsidySum());
            excel.createNewCol(vo.getFreeSubsidyFee());
            excel.createNewCol(vo.getDiscountSubsidySum());
        }
        Map<String, String> datas = new HashMap<String, String>();
        datas.put("title", "财务-业务合并表");
        datas.put("startTime", DateUtil.StringToString(startTime, DateStyle.YYYY_MM_DD_HH_MM_SS));
        datas.put("endTime",DateUtil.StringToString(endTime,DateStyle.YYYY_MM_DD_HH_MM_SS));
        excel.replaceFind(datas);               //替换#开头的单元格数据
        excel.insertSer();                      //插入序号,模版中sernums列
        excel.writeToFile(filePath);
        ExcelUtil.download(filePath, response);
    }


    /** 查询 财务-业务合并表 */
    private List<GeneralTableVO> loadGeneralData(String startTime, String endTime) {
        Map<String,String> map = new HashMap<>();
        map.put("startTime",startTime);
        map.put("endTime",endTime);
        map.put("orderStatus",OrderStatus.VerifiedDateOut.name());
        map.put("timeType",TimeType.examineTime.name());
        String[] dimensionList ={"shop","sportsType","payType","orderType"};
        DataCount data = this.getAllOrder(dimensionList,map);
        List<GeneralTableVO> list = new ArrayList<>();
            for (DataCount shopList :data.getSubSettlements()){        //场馆维度
                Shop shop = this.shopMapper.selectByPrimaryKey(Integer.valueOf(shopList.getValue()));
                for (DataCount sportsType : shopList.getSubSettlements()){           //运动类型维度
                    GeneralTableVO vo = new GeneralTableVO(0,0.0);
                    vo.setShopId(shop.getShopId());
                    vo.setShopCode(shop.getShopCode());
                    vo.setShopName(shop.getShopName());
                    vo.setSportsType(sportsType.getTitle());
                    vo.setTotalOrderNum(sportsType.getCount());
                    vo.setTotalStadiumNum(sportsType.getOrderNum());
                    vo.setTotalSum(sportsType.getTotalSum());
                    vo.setTotalFee(sportsType.getFeeSum());
                    vo.setPaySum(sportsType.getPaySum());
                    vo.setSettleSum(sportsType.getSettlementSum());
                    vo.setOrderFee(sportsType.getFee());
                    vo.setSubsidySum(sportsType.getSubsidySum());
                    vo.setSubsidyFee(sportsType.getSubsidyFee());
                    for (DataCount payType : sportsType.getSubSettlements()) {                  //支付方式维度
                        String payTypeValue = payType.getValue();
                        switch (payTypeValue) {
                            case "VIP":                                         //会员支付
                                for (DataCount orderType : payType.getSubSettlements()) {           //订单类型维度
                                    switch (orderType.getValue()) {
                                        case "DISCOUNT":
                                            vo.setVipDiscountOrderNum(orderType.getCount());
                                            vo.setVipDiscountStadiumNum(orderType.getOrderNum());
                                            vo.setVipDiscountPaySum(orderType.getPaySum());
                                            vo.setVipDiscountSettleSum(orderType.getSettlementSum());
                                            vo.setVipDiscountOrderFee(orderType.getFee());
                                            vo.setVipDiscountSubsidySum(orderType.getSubsidySum());
                                            vo.setVipDiscountSubsidyFee(orderType.getSubsidyFee());
                                            break;
                                        case "PREFERENTIAL":
                                            vo.setVipCheapOrderNum(orderType.getCount());
                                            vo.setVipCheapStadiumNum(orderType.getOrderNum());
                                            vo.setVipCheapPaySum(orderType.getPaySum());
                                            vo.setVipCheapSettleSum(orderType.getSettlementSum());
                                            vo.setVipCheapOrderFee(orderType.getFee());
                                            break;
                                    }
                                }
                                break;
                            case "ALIPAY":                                //支付宝支付
                                for (DataCount orderType : payType.getSubSettlements()) {           //订单类型维度
                                    switch (orderType.getValue()) {
                                        case "DISCOUNT":
                                            vo.setAliDiscountOrderNum(orderType.getCount());
                                            vo.setAliDiscountStadiumNum(orderType.getOrderNum());
                                            vo.setAliDiscountPaySum(orderType.getPaySum());
                                            vo.setAliDiscountSettleSum(orderType.getSettlementSum());
                                            vo.setAliDiscountOrderFee(orderType.getFee());
                                            vo.setAliDiscountSubsidySum(orderType.getSubsidySum());
                                            vo.setAliDiscountSubsidyFee(orderType.getSubsidyFee());
                                            break;
                                        case "PREFERENTIAL":
                                            vo.setAliCheapOrderNum(orderType.getCount());
                                            vo.setAliCheapStadiumNum(orderType.getOrderNum());
                                            vo.setAliCheapPaySum(orderType.getPaySum());
                                            vo.setAliCheapSettleSum(orderType.getSettlementSum());
                                            vo.setAliCheapOrderFee(orderType.getFee());
                                            break;
                                    }
                                }
                                break;
                            case "FREE":                                 //免费
                                vo.setFreeOrderNum(payType.getCount());
                                vo.setFreeStadiumNum(payType.getOrderNum());
                                vo.setFreeSettleSum(payType.getSettlementSum());
                                vo.setFreeSubsidySum(payType.getSubsidySum());
                                vo.setFreeSubsidyFee(payType.getSubsidyFee());
                                break;
                            default:                               //其它支付方式
                                for (DataCount orderType : payType.getSubSettlements()) {           //订单类型维度
                                    switch (orderType.getValue()) {
                                        case "DISCOUNT":
                                            vo.setOtherDiscountOrderNum(vo.getOtherDiscountOrderNum() + orderType.getCount());
                                            vo.setOtherDiscountStadiumNum(vo.getOtherDiscountStadiumNum() + orderType.getOrderNum());
                                            vo.setOtherDiscountPaySum(vo.getOtherDiscountPaySum() + orderType.getPaySum());
                                            vo.setOtherDiscountSettleSum(vo.getOtherDiscountSettleSum() + orderType.getSettlementSum());
                                            vo.setOtherDiscountOrderFee(vo.getOtherDiscountOrderFee() + orderType.getFee());
                                            vo.setOtherDiscountSubsidySum(vo.getOtherDiscountSubsidySum() + orderType.getSubsidySum());
                                            vo.setOtherDiscountSubsidyFee(vo.getOtherDiscountSubsidyFee() + orderType.getSubsidyFee());
                                            break;
                                        case "PREFERENTIAL":
                                            vo.setOtherCheapOrderNum(vo.getOtherCheapOrderNum() + orderType.getCount());
                                            vo.setOtherCheapStadiumNum(vo.getOtherCheapStadiumNum() + orderType.getOrderNum());
                                            vo.setOtherCheapPaySum(vo.getOtherCheapPaySum() + orderType.getPaySum());
                                            vo.setOtherCheapSettleSum(vo.getOtherCheapSettleSum() + orderType.getSettlementSum());
                                            vo.setOtherCheapOrderFee(vo.getOtherCheapOrderFee() + orderType.getFee());
                                            break;
                                    }
                                }
                                break;
                        }
                        vo.setDiscountSubsidySum(vo.getVipDiscountSubsidySum()+vo.getAliDiscountSubsidySum()+vo.getOtherDiscountSubsidySum());
                    }
                    list.add(vo);
                }
            }
        return list;
    }
}
